import datetime
import random

from ckeditor.fields import RichTextField
from django.db import models
from django.db.models import Sum
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _

from jiaozi.utils import model_data_from_cache, hget_data, hset_data


class VipLevel(models.Model):
    level_code = models.SmallIntegerField(verbose_name=_('等级编号'), null=True, unique=True)
    level_name = models.CharField(verbose_name=_('等级名称'), max_length=100, null=True, unique=True)
    desc = models.TextField(verbose_name=_('等级描述'), max_length=1000, null=True, blank=True)

    objects = models.Manager()

    class Meta:
        ordering = ['id']
        verbose_name = _('1.会员等级')
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(
            self.level_code,
            self.level_name,
        )


@receiver(post_save, sender=VipLevel)
def post_save_vip_level(sender, instance, **kwargs):
    model_data_from_cache(sender, instance.pk, force_update=True)


class VipSales(models.Model):
    vip_level = models.ForeignKey(
        VipLevel,
        on_delete=models.CASCADE,
        verbose_name=_('会员等级')
    )
    title = models.CharField(verbose_name=_('明细标题'), max_length=100, default='', blank=True)
    title_image = models.ImageField(verbose_name=_('明细标题图片'), upload_to='media/vip/%Y%m/', null=True, blank=True)
    rules = models.TextField(verbose_name=_('规则'), max_length=1000, default='', blank=True)
    amount_initial = models.IntegerField(verbose_name=_('发售数量'), default=1)
    vip_dates = models.IntegerField(verbose_name=_('会员日期'), default=90)
    vip_start = models.DateTimeField(verbose_name=_('会员开始'), null=True, blank=True)
    vip_end = models.DateTimeField(verbose_name=_('会员结束'), null=True, blank=True)
    main_image = models.ImageField(verbose_name=_('主图片'), upload_to='media/vip/%Y%m/', null=True, blank=True)
    body_cn = RichTextField(verbose_name=_('中文描述'), max_length=20000, null=True, blank=True)
    body_en = RichTextField(verbose_name=_('英文描述'), max_length=20000, null=True, blank=True)
    price_show = models.DecimalField(verbose_name=_('展示价格'), null=True, max_digits=12, decimal_places=2)
    sales_start = models.DateTimeField(verbose_name=_('发售开始'), null=True)
    sales_end = models.DateTimeField(verbose_name=_('发售结束'), null=True)
    is_show = models.BooleanField(verbose_name=_('上架'), default=False)
    datetime_created = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    datetime_updated = models.DateTimeField(verbose_name=_('更新时间'), auto_now=True)

    objects = models.Manager()

    def get_amount_left(self, force_update=True):
        key_name = 'vip_vip_sales_amount_sales'
        if force_update:
            amount_sales = None
        else:
            amount_sales = hget_data(key_name, self.pk)
        if amount_sales is None:
            amount_sales = VipSalesOrder.objects.filter(
                is_payed=True, vip_sales_id=self.pk
            ).count()
            hset_data(key_name, self.pk, amount_sales)
        data = int(self.amount_initial) - amount_sales
        return data

    get_amount_left.short_description = '剩余数量'

    amount_left = property(get_amount_left)

    def total_payed_amount_property(self):
        total_payed = VipSalesOrder.objects.filter(
            is_payed=True, vip_sales_id=self.pk
        ).aggregate(
            total_payed=Sum('price_payed')
        )
        res = 0
        if total_payed:
            res = float(total_payed['total_payed'])
        return res

    total_payed_amount_property.short_description = '总收款'
    total_payed_amount = property(total_payed_amount_property)

    @property
    def can_sale(self):
        res = False
        if self.sales_start < datetime.datetime.now() < self.sales_end:
            if self.amount_left > 0:
                res = True
        return res

    class Meta:
        ordering = ['-id']
        verbose_name = _('2.会员出售')
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(
            self.vip_level,
            self.amount_initial,
        )


@receiver(post_save, sender=VipSales)
def post_save_vip_sales(sender, instance, **kwargs):
    model_data_from_cache(sender, instance.pk, force_update=True)


class VipSalesOrder(models.Model):
    order_number = models.CharField(verbose_name=_('订单号'), max_length=255, null=True, blank=True, unique=True)
    user = models.ForeignKey(
        'app.WxUser',
        on_delete=models.CASCADE,
        verbose_name=_('用户')
    )
    vip_sales = models.ForeignKey(
        VipSales,
        on_delete=models.PROTECT,
        verbose_name=_('会员类型')
    )
    pay_record = models.ForeignKey(
        'money.PayRecord',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_('支付记录')
    )
    # 订单金额合计
    price_initial = models.DecimalField(
        verbose_name=_('订单原价'), null=True, blank=True, max_digits=12, decimal_places=2)
    price_payed = models.DecimalField(
        verbose_name=_('支付金额'), null=True, blank=True, max_digits=12, decimal_places=2)

    amount_used = models.IntegerField(verbose_name=_('使用次数'), default=0)
    # 订单状态
    is_payed = models.BooleanField(verbose_name='已支付', default=False)
    datetime_created = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    datetime_updated = models.DateTimeField(verbose_name=_('更新时间'), auto_now=True)

    objects = models.Manager()

    class Meta:
        ordering = ['-id']
        verbose_name = _('3.会员购买')
        verbose_name_plural = verbose_name

    def make_order_number(self):
        if not self.order_number:
            self.order_number = '{}{}V'.format(
                datetime.datetime.now().strftime('%Y%m%d%H%M%S'),
                random.randrange(100, 999)
            )

    def update_amount_sales(self):
        key_name = 'vip_vip_sales_amount_sales'
        amount_sales = VipSalesOrder.objects.filter(
            is_payed=True, vip_sales_id=self.vip_sales_id
        ).count()
        raw_data = int(amount_sales)
        hset_data(key_name, self.pk, raw_data)

    def get_amount_used(self):
        if not self.is_payed:
            return 0
        from sales.models import OrderItem
        count = OrderItem.objects.filter(
            product_sales_order__is_show=True,
            product_sales_order__user_id=self.user_id,
            product_sales_order__datetime_created__gte=self.vip_sales.vip_start,
            product_sales_order__datetime_created__lte=self.vip_sales.vip_end,
            vip_level=self.vip_sales.vip_level,
        ).count()
        return count

    def __str__(self):
        return "{0} {1}".format(
            self.user,
            self.vip_sales,
        )


@receiver(pre_save, sender=VipSalesOrder)
def pre_save_vip_sales_order(sender, instance, **kwargs):
    instance.make_order_number()


@receiver(post_save, sender=VipSalesOrder)
def post_save_vip_sales_order(sender, instance, **kwargs):
    instance.update_amount_sales()


class UserInvite(models.Model):
    user = models.ForeignKey(
        'app.WxUser',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='user_invite_user',
        verbose_name=_('用户')
    )
    invited_user = models.ForeignKey(
        'app.WxUser',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='user_invite_invited_user',
        verbose_name=_('被邀请用户')
    )
    datetime_created = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    datetime_updated = models.DateTimeField(verbose_name=_('更新时间'), auto_now=True)

    objects = models.Manager()

    class Meta:
        ordering = ['-id']
        verbose_name = _('用户邀请')
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(
            self.user,
            self.invited_user,
        )


def get_remind_user_list():
    from product.views import get_user_can_buy_amount
    current_time = datetime.datetime.now()
    vip_sales_orders = VipSalesOrder.objects.filter(
        is_payed=True,
        vip_sales__vip_start__lt=current_time,
        vip_sales__vip_end__gt=current_time,
        amount_used__lt=12
    ).values('user_id', 'vip_sales__vip_level_id')

    user_list = list()

    for vip_sales_order in vip_sales_orders:
        user_id = vip_sales_order['user_id']
        can_buy_amount, has_bought_product_ids = get_user_can_buy_amount(user_id)
        for vip_level, amount in can_buy_amount.items():
            if amount > 0:
                user_list.append(user_id)

    user_list = list(set(user_list))

    return user_list
